package com.jiangyg.mall.ware.config;

import com.jiangyg.mall.core.utils.Logger;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.TopicExchange;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 类描述：库存服务 RabbitMQ 配置
 *
 * @author jiangyg
 * @date 2022-12-17
 */
@Slf4j
@Configuration
public class WareRabbitConfiguration implements InitializingBean {

    // TODO 实现监听

    /**
     * 功能描述：声明一个 Topic 类型的 stock-event-exchange 交换机
     *
     * @return 交换机
     */
    @Bean
    public TopicExchange stockEventExchange() {
        return new TopicExchange("stock-event-exchange");
    }

    /**
     * 功能描述：声明库存释放队列
     *
     * @return 库存释放队列
     */
    @Bean
    public Queue stockReleaseQueue() {
        return new Queue("stock.release.queue", true, false, false, null);
    }

    /**
     * 功能描述：绑定队列 stock.release.queue 到交换机上，同时指定路由规则 stock.release.main.#
     *
     * @return 绑定器
     */
    @Bean
    public Binding stockReleaseQueueBinding() {
        return new Binding("stock.release.queue",
                Binding.DestinationType.QUEUE,
                "stock-event-exchange",
                "stock.release.main.#",
                null);
    }

    /**
     * 功能描述：声明库存延时队列，消息过期时间默认 50 分钟
     * TODO 过期时间可配置化
     *
     * @return 库存延时队列
     */
    @Bean
    public Queue stockDelayQueue() {
        final Map<String, Object> arguments = new HashMap<>(5);
        arguments.put("x-dead-letter-exchange", "stock.release.queue");
        arguments.put("x-dead-letter-routing-key", "stock.release.main");
        arguments.put("x-message-ttl", TimeUnit.MINUTES.toMillis(50));
        return new Queue("stock.delay.queue", true, false, false, arguments);
    }

    /**
     * 功能描述：绑定队列 stock.delay.queue 到交换机上，同时指定路由规则 stock.locked.main.#
     *
     * @return 绑定器
     */
    @Bean
    public Binding stockDelayQueueBinding() {
        return new Binding("stock.delay.queue",
                Binding.DestinationType.QUEUE,
                "stock-event-exchange",
                "stock.locked.main.#",
                null);
    }

    /**
     * 功能描述：声明订单完成库存队列
     * <p>一般用来拆单等服务</p>
     *
     * @return 订单完成库存
     */
    @Bean
    public Queue orderFinishWareQueue() {
        return new Queue("order.finish.ware.queue", true, false, false, null);
    }

    @Override
    public void afterPropertiesSet() {
        Logger.info(log, () -> "[项目启动]-初始化库存服务的 RabbitMQ 配置……");
    }

}
